﻿namespace LambdaCalc.Core.Tests

open System
open NUnit.Framework

open LambdaCalc.Core

[<TestFixture>]
type ``test core-operations: beta-reduce``() = 

    let sysP = SystemParameters.Default
    let betaReduce = LambdaCalc.Core.Operations.betaReduce sysP

    [<Test>]
    member test.``(\x.x)a -> a``() =
        let input = Application(Abstraction("x", Atom "x"), Atom "a")
        let expectedOutput = Atom "a"
        let result = betaReduce input
        Assert.AreEqual(expectedOutput, result)    
        
    [<Test>]
    member test.``(\xy.yx)ab -> ba``() =
        let input = Application(
                        Application(
                            Abstraction("x", 
                                Abstraction ("y", Application(Atom "y", Atom "x"))),
                             Atom "a"),
                        Atom "b")
        let expectedOutput = Application (Atom "b", Atom "a")
        let result = betaReduce input
        Assert.AreEqual(expectedOutput, result)
        
    [<Test>]
    member test.``(\x.x)((\y.y)a) -> a``() =
        let input = Application(
                        Abstraction("x", Atom "x"),
                        Application(
                            Abstraction("y", Atom "y"),
                            Atom "a"))
        let expectedOutput = Atom "a"
        let result = betaReduce input
        Assert.AreEqual(expectedOutput, result)
        
    [<Test>]
    member test.``\x.(\y.y a) -> \x.a``() =
        let input = Abstraction("x",
                        Application(
                            Abstraction("y", Atom "y"),
                            Atom "a"))
        let expectedOutput = Abstraction("x", Atom "a")
        let result = betaReduce input
        Assert.AreEqual(expectedOutput, result)